package com.gezi.admin.module.code.gentable.table;

import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gezi.admin.aop.log.Logging;
import com.gezi.admin.config.exception.type.ApiException;
import com.gezi.admin.module.code.gentable.table.model.CodeGenTableSearchModel;
import com.gezi.admin.module.config.BaseController;
import com.gezi.admin.module.config.utils.PageUtil;
import com.gezi.admin.module.config.utils.PageVo;
import com.gezi.admin.security.SecurityUtil;
import com.gezi.admin.module.code.gentable.column.CodeGenTableColumnEntity;
import com.gezi.admin.module.code.gentable.column.CodeGenTableColumnService;
import com.gezi.admin.module.code.gentable.table.model.CodeGenTableEditParamModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.util.*;

/**
 * @Author 格子代码
 * @createDate 2024/2/10 09:00
 * @contact 1424529270@qq.com
 */
@Api(tags = "生成代码")
@RestController
@RequestMapping("/api/code/gen/table")
public class CodeGenTableController extends BaseController {

    @Resource
    private CodeGenTableService codeGenTableService;

    @Resource
    private CodeGenTableColumnService codeGenTableColumnService;

    @ApiOperation("查询分页")
    @GetMapping(value = "/findAllByPage")
    public Object findAllByPage(PageVo page, CodeGenTableSearchModel searchVo) {
        Page<Map> pageData = codeGenTableService.findByPage(PageUtil.initMpPage(page), searchVo);
        return pageData;
    }

    @ApiOperation("查询列表")
    @GetMapping(value = "/findAllByList")
    public Object findAllByList(CodeGenTableSearchModel searchVo) {
        String userId = SecurityUtil.getUserId();
        searchVo.setUserId(userId);
        List<Map> list = codeGenTableService.findByList(searchVo);
        return list;
    }

    @ApiOperation("查询详情")
    @GetMapping(value = "/findById/{id}")
    public Map findById(@PathVariable @NotBlank(message = "参数不能为空") String id) {
        CodeGenTableEntity codeGenTableEntity = codeGenTableService.getById(id);
        if (codeGenTableEntity == null) {
            throw ApiException.getInstance("数据不存在，请刷新重试");
        }

        List<CodeGenTableEntity> tables = codeGenTableService.list();
        List<CodeGenTableColumnEntity> list = codeGenTableColumnService.findAllByGenTableId(codeGenTableEntity.getId());
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("info" , codeGenTableEntity);
        List<String> igField = Arrays.asList("id" , "create_by" , "create_time" , "update_time" , "update_by" , "del_flag");
        map.put("rows" , list.stream().sorted(Comparator.comparing(CodeGenTableColumnEntity::getSort)).filter(item -> !igField.contains(item.getColumnName())));
        map.put("tables" , tables);
        return map;
    }

    @ApiOperation("查询数据库分页")
    @GetMapping(value = "/db/findAllByPage")
    public Object dbFindAllByPage(PageVo page, CodeGenTableSearchModel searchVo) {
        Page<Map> pageData = codeGenTableService.dbFindAllByPage(PageUtil.initMpPage(page), searchVo);
        return pageData;
    }

    @ApiOperation("查询表列表")
    @GetMapping(value = "/column/{tableId}")
    public Object findAllByList(@NotNull(message = "数据不存在，请刷新重试")
                                @PathVariable String tableId) {
        List<CodeGenTableColumnEntity> list = codeGenTableColumnService.findAllByGenTableId(tableId);
        return list;
    }

    @ApiOperation("导入表")
    @PostMapping(value = "/importTable")
    public void importTable(@NotBlank(message = "数据不能为空，请刷新重试")
                                @RequestBody Map<String,String> tables) {
        String[] tableNames = Convert.toStrArray(tables.get("tables"));
        // 查询表信息
        List<CodeGenTableEntity> tableList = codeGenTableService.findDbTableListByNames(tableNames);
        codeGenTableService.importGenTable(tableList);
    }

    @ApiOperation("修改")
    @PostMapping(value = "/edit")
    public void edit(@RequestBody Map<String,String> params) {

        CodeGenTableEditParamModel paramModel = JSON.parseObject(params.get("content"), CodeGenTableEditParamModel.class);
        //校验参数
        CodeGenTableEntity codeGenTableEntity = codeGenTableService.getById(paramModel.getId());
        if (codeGenTableEntity == null) {
            throw new ApiException("数据不存在，请刷新重试");
        }

        codeGenTableService.edit(paramModel);
    }

    @ApiOperation("删除")
    @DeleteMapping(value = "/delByIds/{ids}")
    public void delByIds(
            @PathVariable String[] ids) {
        for (String id : ids) {
            CodeGenTableEntity codeGenTableEntity = codeGenTableService.getById(id);
            if (codeGenTableEntity == null) {
                throw new ApiException("数据不存在，请刷新重试");
            }
            //方法二：适合事务删除
            codeGenTableService.del(id);
        }
    }

    @ApiOperation("同步数据库")
    @Logging(tags = "代码生成", value = "同步数据库")
    @GetMapping("/tongbuById/{id}")
    public void tongbuById(@PathVariable("id") String id) {
        codeGenTableService.tongbuById(id);
    }

    @ApiOperation("预览代码")
    @GetMapping("/preview/{id}")
    public Object preview(@PathVariable("id") String id) {
        Map<String, String> dataMap = codeGenTableService.previewCode(id);

        return dataMap;
    }

    @ApiOperation("生成代码-自定义路径")
    @PostMapping("/genCodeById/{id}")
    public void genCode(@PathVariable("id") String id) {
        codeGenTableService.generatorCode(id);
    }

    @ApiOperation("生成代码-下载方式")
    @PostMapping("/download/{id}")
    public void download(HttpServletResponse response, @PathVariable("id") String id) throws IOException {
        byte[] data = codeGenTableService.downloadCode(id);
        genCode(response, data);
    }

    /**
     * 生成zip文件
     */
    private void genCode(HttpServletResponse response, byte[] data) throws IOException {
        response.reset();
        response.addHeader("Access-Control-Allow-Origin" , "*");
        response.addHeader("Access-Control-Expose-Headers" , "Content-Disposition");
        response.setHeader("Content-Disposition" , "attachment; filename=\"格子代码.zip\"");
        response.addHeader("Content-Length" , "" + data.length);
        response.setContentType("application/octet-stream; charset=UTF-8");
        IOUtils.write(data, response.getOutputStream());
    }
}